package com.example.android.utils

import android.content.Context
import com.example.android.R
import com.example.android.utils.models.Form
import com.example.android.utils.models.MyResult
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.JsonObject
import com.google.gson.JsonPrimitive
import com.google.gson.reflect.TypeToken
import org.json.JSONArray
import org.json.JSONObject
import java.security.InvalidParameterException

/**
 * @ClassName JsonUtil
 * @Author Ryan Kamanri
 * @Date 2022/6/1
 * @Description 处理json的工具类封装
 **/
class JsonUtil(_Context: Context) {
    private val _Gson = GsonBuilder()
        .setDateFormat(_Context.getString(R.string.datetime_format_string))
        .create()

    // gson
    fun ToJson(src: Any):String {
        return _Gson.toJson(src)
    }

    fun <T> FromJsonArray(clazz: Class<T>, json: String): ArrayList<T> {
        val jsonArray = JSONArray(json)
        return FromJsonArray(clazz, jsonArray)
    }


    private fun <T> FromJsonArray(clazz: Class<T>, jsonArray: JSONArray): ArrayList<T> {
        val result = arrayListOf<T>()

        for(index in 0 until jsonArray.length()) {
            val jsonItem = jsonArray[index]

            if(jsonItem.javaClass == JSONObject::class.java) {
                result.add(FromJsonObject(clazz, jsonItem as JSONObject))

            } else {
                // Invalid Embed Array
                throw InvalidParameterException("Invalid Type: ${object: TypeToken<T>(){}.type}")
            }
        }
        return result
    }

    private fun <T> FromJsonObject(clazz: Class<T>, jsonObject: JSONObject): T {
        val json = jsonObject.toString()
        return FromJsonObject(clazz, json)
    }

    fun <T> FromJsonObject(clazz: Class<T>, json: String): T {
        return _Gson.fromJson(json, clazz)
    }

    // org.json

    fun FromJsonObject(json: String): Form {
        val jsonObject = JSONObject(json)
        return FromJsonObject(jsonObject)
    }

    private fun FromJsonObject(jsonObject: JSONObject): Form {
        val result = Form()
        jsonObject.keys().forEach {
            val jsonToken = jsonObject[it]
            when(jsonToken.javaClass) {
                JSONObject::class.java -> {
                    result[it] = FromJsonObject(jsonToken as JSONObject)
                }
                JSONArray::class.java -> {
                    result[it] = FromJsonArray(jsonToken as JSONArray)
                }
                else -> result[it] = jsonToken

            }

        }
        return result
    }

    private fun FromJsonArray(jsonArray: JSONArray): ArrayList<Any> {
        val result = ArrayList<Any>()
        for (i in 0 until jsonArray.length()) {
            val jsonToken = jsonArray[i]
            when(jsonToken.javaClass) {
                JSONObject::class.java -> {
                    result.add(FromJsonObject(jsonToken as JSONObject))
                }
                JSONArray::class.java -> {
                    result.add(FromJsonArray(jsonToken as JSONArray))
                }
                else -> result.add(jsonToken)
            }
        }
        return result
    }
}